﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UIShare;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace EFong.Host
{
    class HostUIController
    {
        private static NotifyIcon _notifyIcon = new NotifyIcon();
        private static HostMgt hostMgt = new HostMgt();

        private static ConnectionString connectionString;
        static string PWD = "SeraphimStudio 2010-08-09";

        public static void Start()
        {
            validateByTestVersion();

            try
            {
                ReallyStart(
                    () =>
                    {
                        //try
                        //{
                        //    HostUIEncrypt.Init();
                        //}
                        //catch (Exception e)
                        //{
                        //    throw new SoftDogException(e.Message, e);
                        //}

                        //if (PWD == HostUIEncrypt.ReadDataFromMem())
                        //{
                        //    throw new Exception("加密狗错误");
                        //}
                    }
                    );
            }
            catch (SoftDogException sde) {
                MessageBox.Show( sde.Message );
                return;
            }
        }


        private static void ReallyStart(Action buildingMgt ) {

            loadConnectionString();

            initNotifyIcon();

            initDB();

            if (!object.ReferenceEquals(buildingMgt, null))
            {
                buildingMgt();
                startHost();
            }
            //else
            //{
            //    MessageBox.Show( "没有加密请" ); return;
            //}
            
            Application.Run();

        }

        private static void loadConnectionString()
        {
            connectionString = ConnectionStringManager.LoadByFile();
                        
            if (connectionString == null || connectionString.Port == 0)
            {
                connectionString = FrmDBSetting.SetConnectionString();

                if (connectionString == null)
                {
                    MsgBox.Error("请先设置数据库,否则不能继续运行系统.");
                    Exit();
                }

                if (connectionString.Port == 0) 
                {
                    MsgBox.Error("请先设置服务器端口,否则不能启动服务器.");
                    Exit();
                }
            }
        }

        public static void Exit()
        {
            _notifyIcon.Visible = false;

            stopHost();

            Application.Exit();
        }

        private static void validateByTestVersion()
        {
            //if (DateTime.Now > new DateTime(2010, 12, 17))
            //{
            //    MsgBox.Error("超过试用的时间.");
            //    Exit();
            //    return;
            //}
        }

        #region Host

        private static void startHost()
        {
            hostMgt.Start(connectionString.Port);
        }

        private static void stopHost()
        {
            hostMgt.Stop();
        }

        #endregion

        #region DB
        private static void initDB()
        {


            ConnectionStringManager.SetConnectionString(connectionString);
        }

        private static void setDB()
        {
            ConnectionString connectionString = FrmDBSetting.SetConnectionString();
            if (connectionString != null)
            {
                ConnectionStringManager.SetConnectionString(connectionString);
                hostMgt.Stop();
                hostMgt.Start(connectionString.Port);
            }
        }
        #endregion

        #region Notify Icon

        private static void initNotifyIcon()
        {

            initNotifyIconMenu();

            _notifyIcon.Icon = EFong.Host.Properties.Resources.Icon;

            _notifyIcon.Visible = true;
        }

        private static void initNotifyIconMenu()
        {
            ContextMenuStrip contextMenu = new ContextMenuStrip();

            ToolStripMenuItem tsm_DBSetting = new ToolStripMenuItem("设置服务器", null, tsm_DBSetting_Click);

            ToolStripMenuItem tsm_Exit = new ToolStripMenuItem("退出(&X)", null, tsm_Exit_Click);

            contextMenu.Items.AddRange(new ToolStripItem[] { 
                tsm_DBSetting,
                new ToolStripSeparator(),
                tsm_Exit
            });

            _notifyIcon.ContextMenuStrip = contextMenu;
        }

        #endregion

        private static void tsm_DBSetting_Click(object sender, EventArgs e)
        {
            setDB();
        }

        private static void tsm_Exit_Click(object sender, EventArgs e)
        {
            Exit();
        }
    }


    class HostUIEncrypt {


        /* 加密锁区号 */
        internal static String SD_Encrypt_Nr = "";

        /* 加密锁唯一ID */
        internal static String SD_Locked_Id = "";

        /* 加密狗版本号 */
        internal static short SD_Version = 0;

        /* 低4位密码 */
        internal static string SD_LPWD_1 = "";

        /* 高4位密码 */
        internal static string SD_HPWD_2 = "";


        internal static void Init(string hPwd = "ffffffff", string lPwd = "ffffffff")
        {

#if DEBUG
            Debug.Assert(String.Empty.CompareTo(hPwd) != 0, "高密码不能为空");
            Debug.Assert(String.Empty.CompareTo(lPwd) != 0, "低密码不能为空");
#endif

            SD_HPWD_2 = hPwd;
            SD_LPWD_1 = lPwd;


            InitLockId();
            InitEncryptNr();
            InitVersion();

        }

        /*'用于返回加密狗的ID号，加密狗的ID号由两个长整型组成。
          '提示1：锁ID每一把都是唯一的，每一把锁的ID都不相同
          '提示2: ID唯一是指两个ID转化为16进制字符串后并连接起来后是唯一的
         */
        static void InitLockId()
        {

            StringBuilder devicePath = new StringBuilder(String.Empty, 256);

            if (0 != SoftDogAPI.FindPort( /* 从那个加密位置开始 */ 0, devicePath))
            {
                throw (new Exception("未找到加密锁,请插入加密锁后，再进行操作."));
                return;
            }

            SD_Locked_Id = devicePath.ToString();

        }

        /* 这个用于判断系统中是否存在着加密锁。不需要是指定的加密锁 */
        static void InitEncryptNr()
        {
#if DEBUG
            Debug.Assert(String.Empty.CompareTo(SD_Locked_Id) != 0, "加密锁区号");
#endif

            int id_1 = 0, id_2 = 0;

            if (0 != SoftDogAPI.GetID(ref id_1, ref id_2, SD_Locked_Id))
            {
                throw (new Exception("返回ID错误"));
                return;
            }

            SD_Encrypt_Nr = id_1.ToString("X") + id_2.ToString("X");
        }

        /* 用于返回加密狗的版本号 */
        static void InitVersion()
        {

#if DEBUG
            Debug.Assert(String.Empty.CompareTo(SD_Locked_Id) != 0, "加密锁区号");
#endif
            unchecked
            {
                if (0 != SoftDogAPI.NT_GetIDVersion(ref SD_Version, SD_Locked_Id))
                {
                    throw (new Exception("返回版本号错误"));
                }
            }
        }

        internal static string ReadDataFromMem()
        {

            /* 读取部分头信息 */
            short nlen = (short)1;
            int ret = 0;
            byte b = new byte();

            if (0 != (ret = SoftDogAPI.YRead(ref b, 0, SD_HPWD_2, SD_LPWD_1, SD_Locked_Id)))
            {
                throw (new Exception("读取符串失败"));
            }
            
            /* 读取主体信息 */
            byte[] otBuff = new byte[ Convert.ToInt32(b) ];
            if (0 != (ret = SoftDogAPI.YReadEx(otBuff, nlen, (short)otBuff.Length, SD_HPWD_2, SD_LPWD_1, SD_Locked_Id)))
            {
                throw (new Exception("读取符串失败"));
            }

            return Convert.ToString(otBuff);
        }


    }


    [Serializable]
    public class SoftDogException : Exception
    {
        public SoftDogException() { }
        public SoftDogException(string message) : base(message) { }
        public SoftDogException(string message, Exception inner) : base(message, inner) { }
        protected SoftDogException(
          System.Runtime.Serialization.SerializationInfo info,
          System.Runtime.Serialization.StreamingContext context)
            : base(info, context) { }
    }


    internal static class SoftDogAPI
    {

        //查找指定的加密锁
        [DllImport("SYUNEW3D.dll")]
        public static extern int FindPort(int start, StringBuilder OutKeyPath);

        //获到锁的版本
        [DllImport("SYUNEW3D.dll")]
        public static extern int NT_GetIDVersion(ref short version, string KeyPath);

        //查找加密锁
        [DllImport("SYUNEW3D.dll")]
        public static extern int FindPort_2(int start, int in_data, int verf_data, StringBuilder OutKeyPath);

        //获到锁的ID
        [DllImport("SYUNEW3D.dll")]
        public static extern int GetID(ref int id_1, ref int id_2, string KeyPath);

        //从加密锁中读取一批字节
        [DllImport("SYUNEW3D.dll")]
        public static extern int YReadEx(byte[] OutData, short Address, short mylen, string HKey, string LKey, string KeyPath);

        //从加密锁中读取一个字节数据，一般不使用
        [DllImport("SYUNEW3D.dll")]
        public static extern int YRead(ref byte OutData, short Address, string HKey, string LKey, string KeyPath);

        //写一批字节到加密锁中
        [DllImport("SYUNEW3D.dll")]
        public static extern int YWriteEx(byte[] InData, short Address, short mylen, string HKey, string LKey, string KeyPath);

        //写一个字节的数据到加密锁中，一般不使用
        [DllImport("SYUNEW3D.dll")]
        public static extern int YWrite(byte InData, short Address, string HKey, string LKey, string KeyPath);

        //从加密锁中读字符串
        [DllImport("SYUNEW3D.dll")]
        public static extern int YReadString(StringBuilder outstring, short Address, short mylen, string HKey, string LKey, string KeyPath);

        //写字符串到加密锁中
        [DllImport("SYUNEW3D.dll")]
        public static extern int YWriteString(string InString, short Address, string HKey, string LKey, string KeyPath);

        //算法函数
        [DllImport("SYUNEW3D.dll")]
        public static extern int sWriteEx(int in_data, ref int out_data, string KeyPath);

        [DllImport("SYUNEW3D.dll")]
        public static extern int sWrite_2Ex(int in_data, ref int out_data, string KeyPath);

        [DllImport("SYUNEW3D.dll")]
        public static extern int sRead(ref int in_data, string KeyPath);

        [DllImport("SYUNEW3D.dll")]
        public static extern int sWrite(int out_data, string KeyPath);

        [DllImport("SYUNEW3D.dll")]
        public static extern int sWrite_2(int out_data, string KeyPath);

        //设置写密码
        [DllImport("SYUNEW3D.dll")]
        public static extern int SetWritePassword(string W_HKey, string W_LKey, string new_HKey, string new_LKey, string KeyPath);

        //设置读密码
        [DllImport("SYUNEW3D.dll")]
        public static extern int SetReadPassword(string W_HKey, string W_LKey, string new_HKey, string new_LKey, string KeyPath);

        //'设置扩展算法密钥
        [DllImport("SYUNEW3D.dll")]
        public static extern int SetCal_2(string Key, string KeyPath);

        //使用增强算法对字符串进行加密
        [DllImport("SYUNEW3D.dll")]
        public static extern int EncString(string InString, StringBuilder outstring, string KeyPath);

        //使用增强算法对字符串进行解密
        [DllImport("SYUNEW3D.dll")]
        public static extern void DecString(string InString, StringBuilder outstring, string InKey);

        //使用增强算法对二进制数据进行加密
        [DllImport("SYUNEW3D.dll")]
        public static extern int Cal(byte[] InBuf, byte[] OutBuf, string KeyPath);

        //获取字符串长度
        [DllImport("SYUNEW3D.dll")]
        public static extern int GetLen(string InString);

        [DllImport("kernel32.dll")]
        public static extern int lstrlenA(string InString);

    }





}
